﻿using System;
using FreeSql;
using EAF.DBC;
using EAF.Utility;

namespace App.Model
{
    /// <summary>
    /// AppLog数据库dbContext 对应一个数据库
    /// </summary>
    public class AppLogContext : BaseDbContext
    {
        /// <summary>
        /// 假删除过滤器key
        /// </summary>
        public const string SoftDeleteKey = "SoftDelete";

        //缓存的key
        private const string dbKey = "SQL.Log";
        //数据库类型
        private const FreeSql.DataType dbType = DataType.MySql;


        public AppLogContext() : base(dbType, AppConfig.AllValue["SQL.Log"])
        {
            IniFreeSql();
        }

        /// <summary>
        /// 创建db上下文 可传入数据库类型和连接字符串 
        /// </summary>
        /// <param name="dataType"></param>
        /// <param name="connString"></param>
        public AppLogContext(DataType dataType, string connString) : base(dataType, connString)
        {
            IniFreeSql();
        }

        private void IniFreeSql()
        {
            //尝试获取db实例 没有则创建
            var fsql = DbContextPool.GetDbContext(dbKey);
            if (fsql == null)
            {
                //配置freesql实例 数据库相关配置都在此方法 处理db类型和连接字符串 
                fsql = new FreeSql.FreeSqlBuilder()
                    .UseConnectionString(DbType, ConnectionString)
                    .UseNameConvert(FreeSql.Internal.NameConvertType.PascalCaseToUnderscoreWithLower)               //表名和字段名使用user_name这种格式
                    .UseAutoSyncStructure(false)
                    .UseNoneCommandParameter(true)
                    .UseLazyLoading(false)      //导航属性懒加载
                    .UseMonitorCommand(DbContextPool.ExecuteSqlBefore, DbContextPool.ExecuteSqlAfter)
                    //.UseConfigEntityFromDbFirst(true)
                    .Build();

                //自定义类型映射 枚举统一映射int
                fsql.Aop.ConfigEntityProperty += (s, cep) =>
                {
                    //默认情况 c# 枚举会映射为 MySql Enum 类型，如果想映射为 int 在 FreeSqlBuilder Build 之后执行以下 Aop 统一处理。https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
                    // if (fsql.Ado.DataType == DataType.MySql && ce.Property.PropertyType.IsEnum)
                    //     ce.ModifyResult.MapType = typeof(int);
                    //为了LookSQL能正常显示Enum特性的值
                    if (cep.Property.PropertyType.IsEnum)
                        cep.ModifyResult.MapType = typeof(int);
                };

                //全局过滤器
                fsql.GlobalFilter
                    .Apply<EntityBase<int>>(SoftDeleteKey, w => w.Deleted == false);     //假删除

                //添加到缓存
                DbContextPool.AddDbContext(dbKey, fsql);
            }

            base.UseFreeSql(fsql);
        }


    }
}
